using System;
using System.Collections;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;


public class WebSocketClient : MonoBehaviour
    {
        [Header("WebSocket设置")]
        [SerializeField] private string serverUrl = "ws://localhost:8080"; // WebSocket服务器地址
        [SerializeField] private float reconnectInterval = 5f; // 重连间隔时间
        [SerializeField] private bool autoConnectOnStart = true; // 是否在启动时自动连接
        
        [Header("调试选项")]
        [SerializeField] private bool enableDebugLogs = true; // 是否启用调试日志
        
        private ClientWebSocket websocket;
        private CancellationTokenSource cancellationTokenSource;
        private bool isConnecting = false;
        private bool shouldReconnect = true;
        private Coroutine reconnectCoroutine;
        private Task receiveTask;
        // 事件定义
        public event Action OnConnected; // 连接成功事件
        public event Action OnDisconnected; // 连接断开事件
        public event Action<SmartBedData> OnDataReceived; // 数据接收事件
        public event Action<string> OnError; // 错误事件
        
        // 当前数据
        private SmartBedData currentBedData;
        private int totalMessagesReceived = 0;
        private DateTime lastDataReceivedTime;
        
        private void Start()
        {
            // 自动连接
            if (autoConnectOnStart)
            {
                Connect();
            }
        }
        
        private void OnDestroy()
        {
            shouldReconnect = false;
            
            Disconnect();
        }
        
        /// <summary>
        /// 连接WebSocket服务器
        /// </summary>
        public void Connect()
        {
            if (websocket != null && websocket.State == WebSocketState.Open)
            {
                LogDebug("WebSocket已经连接");
                return;
            }
            
            if (isConnecting)
            {
                LogDebug("正在连接中...");
                return;
            }
            
            isConnecting = true;
            
            try
            {
                // 创建WebSocket实例
                websocket = new ClientWebSocket();
                cancellationTokenSource = new CancellationTokenSource();
                
                // 开始连接
                ConnectAsync();
            }
            catch (Exception e)
            {
                LogError($"连接WebSocket失败: {e.Message}");
                isConnecting = false;
                OnError?.Invoke(e.Message);
                
                // 启动重连
                if (shouldReconnect)
                {
                    StartReconnect();
                }
            }
        }
        
        /// <summary>
        /// 异步连接WebSocket服务器
        /// </summary>
        private async void ConnectAsync()
        {
            try
            {
                LogDebug($"正在连接到WebSocket服务器: {serverUrl}");
                
                // 连接到服务器
                await websocket.ConnectAsync(new Uri(serverUrl), cancellationTokenSource.Token);
                
                isConnecting = false;
                LogDebug("WebSocket连接成功");
                OnConnected?.Invoke();
                
                // 开始接收消息
                receiveTask = ReceiveMessagesAsync();
            }
            catch (Exception e)
            {
                LogError($"连接WebSocket失败: {e.Message}");
                isConnecting = false;
                OnError?.Invoke(e.Message);
                
                // 启动重连
                if (shouldReconnect)
                {
                    StartReconnect();
                }
            }
        }
        
        /// <summary>
        /// 异步接收消息
        /// </summary>
        private async Task ReceiveMessagesAsync()
        {
            var buffer = new byte[4096];
            var segment = new ArraySegment<byte>(buffer);
            
            try
            {
                while (websocket.State == WebSocketState.Open && !cancellationTokenSource.Token.IsCancellationRequested)
                {
                    WebSocketReceiveResult result;
                    using (var ms = new System.IO.MemoryStream())
                    {
                        do
                        {
                            result = await websocket.ReceiveAsync(segment, cancellationTokenSource.Token);
                            if (result.Count > 0)
                            {
                                ms.Write(buffer, 0, result.Count);
                            }
                        } while (!result.EndOfMessage);
                        
                        if (result.MessageType == WebSocketMessageType.Text)
                        {
                            var message = Encoding.UTF8.GetString(ms.ToArray());
                            OnWebSocketMessage(message);
                        }
                        else if (result.MessageType == WebSocketMessageType.Close)
                        {
                            await websocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", cancellationTokenSource.Token);
                            OnWebSocketClose("服务器关闭连接");
                        }
                    }
                }
            }
            catch (WebSocketException e)
            {
                LogError($"WebSocket异常: {e.Message}");
                OnError?.Invoke(e.Message);
                OnWebSocketClose($"连接异常: {e.Message}");
            }
            catch (OperationCanceledException)
            {
                // 正常取消，不做处理
            }
            catch (Exception e)
            {
                LogError($"接收消息异常: {e.Message}");
                OnError?.Invoke(e.Message);
                OnWebSocketClose($"接收消息异常: {e.Message}");
            }
        }
        
        /// <summary>
        /// 断开WebSocket连接
        /// </summary>
        public void Disconnect()
        {
            shouldReconnect = false;
            
            if (reconnectCoroutine != null)
            {
                StopCoroutine(reconnectCoroutine);
                reconnectCoroutine = null;
            }
            
            if (cancellationTokenSource != null)
            {
                cancellationTokenSource.Cancel();
                cancellationTokenSource.Dispose();
                cancellationTokenSource = null;
            }
            
            if (websocket != null)
            {
                if (websocket.State == WebSocketState.Open)
                {
                    try
                    {
                        websocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None).Wait();
                    }
                    catch (Exception e)
                    {
                        LogError($"关闭WebSocket连接失败: {e.Message}");
                    }
                }
                
                websocket.Dispose();
                websocket = null;
            }
            
            isConnecting = false;
            LogDebug("WebSocket连接已断开");
            OnDisconnected?.Invoke();
        }
        
        /// <summary>
        /// 发送消息到服务器
        /// </summary>
        public async void SendMessage(string message)
        {
            if (websocket != null && websocket.State == WebSocketState.Open)
            {
                try
                {
                    var buffer = Encoding.UTF8.GetBytes(message);
                    var segment = new ArraySegment<byte>(buffer);
                    await websocket.SendAsync(segment, WebSocketMessageType.Text, true, cancellationTokenSource.Token);
                    LogDebug($"发送消息: {message}");
                }
                catch (Exception e)
                {
                    LogError($"发送消息失败: {e.Message}");
                    OnError?.Invoke(e.Message);
                }
            }
            else
            {
                LogWarning("WebSocket未连接，无法发送消息");
            }
        }
        
        /// <summary>
        /// WebSocket接收消息回调
        /// </summary>
        private void OnWebSocketMessage(string message)
        {
            try
            {
                string jsonString = message;
                LogDebug($"接收到的JSON数据: {jsonString}");
                
                // 解析JSON数据
                SmartBedData bedData = JsonUtility.FromJson<SmartBedData>(jsonString);
                
                if (bedData != null)
                {
                    // 解析数组数据
                    bedData.ParseData();
                    
                    // 保存当前数据
                    currentBedData = bedData;
                    totalMessagesReceived++;
                    lastDataReceivedTime = DateTime.Now;
                    
                    
                    // 处理数据
                    ProcessBedData(bedData);
                    
                    // 触发数据接收事件
                    OnDataReceived?.Invoke(bedData);
                }
                else
                {
                    LogWarning("JSON数据解析失败");
                }
            }
            catch (Exception ex)
            {
                LogError($"处理WebSocket消息失败: {ex.Message}");
                OnError?.Invoke(ex.Message);
            }
        }
        
        /// <summary>
        /// WebSocket连接关闭回调
        /// </summary>
        private void OnWebSocketClose(string reason)
        {
            isConnecting = false;
            LogDebug($"WebSocket连接关闭: {reason}");
            OnDisconnected?.Invoke();
            
            // 启动重连
            if (shouldReconnect)
            {
                StartReconnect();
            }
        }
        
        /// <summary>
        /// 启动重连协程
        /// </summary>
        private void StartReconnect()
        {
            if (reconnectCoroutine != null)
            {
                StopCoroutine(reconnectCoroutine);
            }
            
            reconnectCoroutine = StartCoroutine(ReconnectCoroutine());
        }
        
        /// <summary>
        /// 重连协程
        /// </summary>
        private IEnumerator ReconnectCoroutine()
        {
            LogDebug($"将在{reconnectInterval}秒后尝试重新连接...");
            
            yield return new WaitForSeconds(reconnectInterval);
            
            if (shouldReconnect)
            {
                Connect();
            }
        }
        
        /// <summary>
        /// 设置服务器URL
        /// </summary>
        public void SetServerUrl(string url)
        {
            serverUrl = url;
            LogDebug($"服务器URL已更新为: {url}");
        }
        
        /// <summary>
        /// 获取连接状态
        /// </summary>
        public bool IsConnected()
        {
            return websocket != null && websocket.State == WebSocketState.Open;
        }
        
        /// <summary>
        /// 获取连接状态字符串
        /// </summary>
        public string GetConnectionState()
        {
            if (websocket == null)
            {
                return "未初始化";
            }
            
            return websocket.State.ToString();
        }
        
        #region 调试日志方法
        
        private void LogDebug(string message)
        {
            if (enableDebugLogs)
            {
                Debug.Log($"[WebSocketClient] {message}");
            }
        }
        
        private void LogWarning(string message)
        {
            Debug.LogWarning($"[WebSocketClient] {message}");
        }
        
        private void LogError(string message)
        {
            Debug.LogError($"[WebSocketClient] {message}");
        }
        
        #endregion
        
        /// <summary>
        /// 处理智能床数据
        /// </summary>
        private void ProcessBedData(SmartBedData bedData)
        {
            // 在这里添加数据处理逻辑
            LogDebug($"处理智能床数据 - 时间: {bedData.time}, 侧面: {bedData.side}");
            
            // 示例：根据姿势状态执行不同操作
            switch (bedData.posture.ToLower())
            {
                case "yes":
                    LogDebug("检测到正确姿势");
                    break;
                case "no":
                    LogDebug("检测到不正确姿势");
                    break;
                default:
                    LogDebug($"未知姿势状态: {bedData.posture}");
                    break;
            }
            
            // 示例：根据气囊状态执行不同操作
            switch (bedData.airbag_status.ToLower())
            {
                case "open":
                    LogDebug("气囊已开启");
                    break;
                case "close":
                    LogDebug("气囊已关闭");
                    break;
                default:
                    LogDebug($"未知气囊状态: {bedData.airbag_status}");
                    break;
            }
            
            // 示例：分析压力数据
            if (bedData.pressureArray != null && bedData.pressureArray.Length > 0)
            {
                int maxPressure = 0;
                int pressurePointsCount = 0;
                
                foreach (int pressure in bedData.pressureArray)
                {
                    if (pressure > 0)
                    {
                        pressurePointsCount++;
                        if (pressure > maxPressure)
                        {
                            maxPressure = pressure;
                        }
                    }
                }
                
                LogDebug($"压力分析 - 检测到{pressurePointsCount}个压力点，最大压力值: {maxPressure}");
            }
        }
        
        /// <summary>
        /// 获取当前智能床数据
        /// </summary>
        public SmartBedData GetCurrentBedData()
        {
            return currentBedData;
        }
        
        /// <summary>
        /// 获取接收到的消息总数
        /// </summary>
        public int GetTotalMessagesReceived()
        {
            return totalMessagesReceived;
        }
        
        #region Unity Editor调试方法
        
        // 在Unity编辑器中添加调试按钮
        [ContextMenu("连接到服务器")]
        private void ConnectInEditor()
        {
            Connect();
        }
        
        [ContextMenu("断开服务器连接")]
        private void DisconnectInEditor()
        {
            Disconnect();
        }
        
        [ContextMenu("打印当前数据")]
        private void PrintCurrentData()
        {
            if (currentBedData != null)
            {
                LogDebug($"当前智能床数据:\n" +
                         $"时间: {currentBedData.time}\n" +
                         $"侧面: {currentBedData.side}\n" +
                         $"姿势: {currentBedData.posture}\n" +
                         $"气囊状态: {currentBedData.airbag_status}\n" +
                         $"平均压力: {currentBedData.avg_pressure}\n" +
                         $"舒适度: {currentBedData.com_level}%\n" +
                         $"接收消息总数: {totalMessagesReceived}");
            }
            else
            {
                LogDebug("暂无数据");
            }
        }
        
        #endregion
}